import 'dart:developer';

import 'terms.dart';

/// 打吃
bool isEat(Board board, ChessStep chessStep) {
  final tempBoard = Board(board.getBoardSize());
  final steps = board.allStep;
  if (steps.length < 5) return false;

  tempBoard.showYzSteps(steps.substring(0, steps.length - 5));

  // 检查周围棋子是否处于打吃状态
  final nearList =
      getNearChess(tempBoard, chessStep, mode: ColorMode.different);
  return nearList.any((position) => tempBoard.airCount(position) == 1);
}

/// 双虎
int isDoubleTiger(Board board, ChessStep chessStep) {
  if (!_isValidPosition(chessStep.x, chessStep.y)) return 0;

  final x = chessStep.x.toInt();
  final y = chessStep.y.toInt();
  final bw = chessStep.bw;

  /// 获取相对位置的棋子颜色
  int chessBw(int dx, int dy) {
    final nx = x + dx, ny = y + dy;
    return _isValidPosition(nx, ny) ? board.getChessValue(nx, ny) : -1;
  }

  /// 判断五个点的配置（用于双虎）
  bool checkFivePoint(int i1, int i2, int i3, int i4, int i5) {
    return chessBw(directions[i1][0], directions[i1][1]) == bw &&
        chessBw(directions[i2][0], directions[i2][1]) == bw &&
        chessBw(directions[i3][0], directions[i3][1]) == bw &&
        chessBw(directions[i4][0], directions[i4][1]) == 0 &&
        chessBw(directions[i5][0], directions[i5][1]) == 0;
  }

  /// 判断四个点的配置（用于单虎）
  bool checkFourPoint(int i1, int i2, int i3, int i4) {
    final bw1 = chessBw(directions[i1][0], directions[i1][1]);
    final bw2 = chessBw(directions[i2][0], directions[i2][1]);
    final bw3 = chessBw(directions[i3][0], directions[i3][1]);
    final bw4 = chessBw(directions[i4][0], directions[i4][1]);

    return bw1 == bw && bw2 == bw && bw3 == 0 && bw4 != 3 - bw; // bw4不能是对方棋子
  }

  // 双虎模式判断
  final doubleTigerPatterns = [
    [1, 2, 7, 9, 11],
    [4, 3, 5, 8, 10],
    [5, 6, 7, 9, 10],
    [4, 0, 1, 8, 11]
  ];

  for (final pattern in doubleTigerPatterns) {
    if (checkFivePoint(
        pattern[0], pattern[1], pattern[2], pattern[3], pattern[4])) {
      return 1; // 双虎
    }
  }

  // 单虎模式判断
  final singleTigerPatterns = [
    [0, 2, 11, 1],
    [0, 3, 8, 4],
    [0, 4, 8, 3],
    [0, 1, 11, 2],
    [1, 2, 11, 0],
    [2, 7, 9, 6],
    [2, 6, 9, 7],
    [3, 4, 8, 0],
    [3, 5, 10, 6],
    [3, 6, 10, 5],
    [5, 6, 10, 3],
    [6, 7, 9, 2]
  ];

  for (final pattern in singleTigerPatterns) {
    if (checkFourPoint(pattern[0], pattern[1], pattern[2], pattern[3])) {
      return 2; // 单虎
    }
  }

  return 0;
}

/// 做眼判断
bool isMakeEye(Board board, ChessStep chessStep) {
  if (!_isValidPosition(chessStep.x, chessStep.y)) {
    return false;
  }

  final x = chessStep.x.toInt();
  final y = chessStep.y.toInt();
  final bw = chessStep.bw;

  /// 获取相对位置的棋子颜色
  int chessBw(int dx, int dy) {
    final nx = x + dx, ny = y + dy;
    return _isValidPosition(nx, ny) ? board.getChessValue(nx, ny) : -1;
  }

  bool checkEyePattern(int i1, int i2, int i3, int i4) {
    final bw1 = chessBw(directions[i1][0], directions[i1][1]);
    final bw2 = chessBw(directions[i2][0], directions[i2][1]);
    final bw3 = chessBw(directions[i3][0], directions[i3][1]);
    final bw4 = chessBw(directions[i4][0], directions[i4][1]);

    if (bw3 == -1) {
      if (bw1 == -1) {
        return bw4 == bw && bw2 == 0;
      } else if (bw4 == -1) {
        return bw1 == bw && bw2 == 0;
      } else {
        return bw1 == bw && bw2 == 0 && bw4 == bw;
      }
    } else {
      if (bw1 == -1) {
        return bw2 == 0 && bw3 == bw && bw4 == bw;
      }
      if (bw4 == -1) {
        return bw1 == bw && bw2 == 0 && bw3 == bw;
      }
    }

    return bw1 == bw && bw2 == 0 && bw3 == bw && bw4 == bw;
  }

  final pattern1 = checkEyePattern(0, 11, 1, 2);
  final pattern2 = checkEyePattern(3, 8, 4, 0);
  final pattern3 = checkEyePattern(6, 10, 5, 3);
  final pattern4 = checkEyePattern(2, 9, 7, 6);

  return pattern1 || pattern2 || pattern3 || pattern4;
}

bool _isValidPosition(int x, int y) {
  return x >= 1 && y >= 1 && x <= 19 && y <= 19;
}

/// 断/粘/团判断
bool isBreak(Board board, ChessStep chessStep, {int type = 0}) {
  // 边界检查
  if (chessStep.x <= 0 ||
      chessStep.y <= 0 ||
      chessStep.x >= 19 ||
      chessStep.y >= 19) {
    return false;
  }

  final x = chessStep.x.toInt();
  final y = chessStep.y.toInt();
  final bw = chessStep.bw;

  int chessBw(int dx, int dy) {
    final nx = x + dx, ny = y + dy;
    return _isValidPosition(nx, ny) ? board.getChessValue(nx, ny) : -1;
  }

  // 定义四个检查模式
  const patterns = [
    [
      [-1, -1],
      [0, -1],
      [-1, 0]
    ], // 左上、左、上
    [
      [1, 1],
      [0, 1],
      [1, 0]
    ], // 右下、右、下
    [
      [-1, 1],
      [0, 1],
      [-1, 0]
    ], // 右上、右、上
    [
      [1, -1],
      [0, -1],
      [1, 0]
    ] // 左下、左、下
  ];

  /// 根据类型确定期望的棋子颜色
  int getExpectedColor(int positionType) {
    switch (type) {
      case 0:
        return positionType == 1 ? bw : 3 - bw; // 断：第一个位置是己方，其他是对方
      case 1:
        return positionType == 1 ? 3 - bw : bw; // 粘：第一个位置是对方，其他是己方
      case 2:
        return 0; // 团：所有位置都应该是空
      default:
        return -1;
    }
  }

  // 检查每个模式
  for (final pattern in patterns) {
    final expected1 = getExpectedColor(1);
    final expected2 = getExpectedColor(2);
    final expected3 = getExpectedColor(3);

    if (expected1 == -1 || expected2 == -1 || expected3 == -1) continue;

    final bw1 = chessBw(pattern[0][0], pattern[0][1]);
    final bw2 = chessBw(pattern[1][0], pattern[1][1]);
    final bw3 = chessBw(pattern[2][0], pattern[2][1]);

    if (bw1 == expected1 && bw2 == expected2 && bw3 == expected3) {
      return true;
    }
  }

  return false;
}

/// 挤的判断
bool isCrowd(Board board, ChessStep chessStep) {
  final x = chessStep.x.toInt();
  final y = chessStep.y.toInt();
  final bw = chessStep.bw;

  /// 检查位置是否有效且有棋子
  bool isValidAndHasChess(int nx, int ny) {
    return _isValidPosition(nx, ny) && board.getChessValue(nx, ny) > 0;
  }

  const directions = [
    [0, -1], [0, 1], [-1, 0], [1, 0] // 左、右、上、下
  ];

  // 统计周围同色和异色棋子数量
  var sameCount = 0, differentCount = 0;

  for (final d in directions) {
    final nx = x + d[0], ny = y + d[1];
    if (isValidAndHasChess(nx, ny)) {
      final neighborColor = board.getChessValue(nx, ny);
      if (neighborColor == bw) {
        sameCount++;
      } else if (neighborColor == 3 - bw) {
        differentCount++;
      }
    }
  }

  // 挤的条件：四个方向都有棋子，且只有1个同色，3个异色
  return sameCount + differentCount == 4 &&
      sameCount == 1 &&
      differentCount == 3;
}

/// 夹
bool isClamp(Board board, ChessStep chessStep, {int type = 0}) {
  int x = chessStep.x;
  int y = chessStep.y;
  int bw = chessStep.bw;

  int chessBw(int dx, int dy) {
    if (x + dx <= 0 || y + dy <= 0) {
      return -1;
    }
    if (x + dx >= 20 || y + dy >= 20) {
      return -1;
    }
    return board.getChessValue(x + dx, y + dy);
  }

  List<List<int>> directions = [
    [-2, 0], //上2
    [2, 0], //下2
    [0, -2], //左2
    [0, 2] // 右2
  ];

  bool check(int i1) {
    int bw1 = chessBw(directions[i1][0], directions[i1][1]);
    return bw1 == bw;
  }

  return check(type);
}

/// 打入
bool judgeInvasion(Board board, ChessStep chessStep) {
  printInfo('判断打入');
  bool haveOppositeChess = false;
  List nonZeroSteps = getNonZeroChessSteps(board);
  for (final step in nonZeroSteps) {
    final distance = distanceSquared(chessStep, step.x, step.y);
    if (distance > 0) {
      if (distance < 17) {
        haveOppositeChess = true;
        printInfo('distance:$distance');
      }
    }
  }
  return haveOppositeChess;
}

/// 前几手的术语
String backTerms(int num, Board board) {
  if (num >= board.getCount()) {
    return '';
  }
  for (var it in chessTerms) {
    if (it.count == board.getCount() - num) {
      return it.terms;
    }
  }
  return '';
}

/// 后几手的术语
String nextTerms(int num, Board board, String originAllStep, {int type = 0}) {
  // printInfo('originAllStep:$originAllStep');

  var tempBoard = Board(board.getBoardSize());
  tempBoard.showYzSteps(originAllStep);

  tempBoard.back(tempBoard.getCount() - board.getCount() - num);

  // printInfo('count:${tempBoard.getCount()}');

  var terms = termsInfo(tempBoard, type: type);
  log('temp_terms:$terms');
  return terms;
}

List<ChessStep> sCount(
    Board board, ChessStep chessStep, int targetDistance, bool sameColor) {
  final nonZeroSteps = getNonZeroChessSteps(board);
  List<ChessStep> stepList = [];

  for (final step in nonZeroSteps) {
    final distance = distanceSquared(chessStep, step.x, step.y);
    if (distance == targetDistance) {
      bool colorMatch =
          sameColor ? step.bw == chessStep.bw : step.bw != chessStep.bw;
      if (colorMatch) {
        stepList.add(step);
      }
    }
  }

  return stepList;
}
